package spring.chatroom.java_chatroom.controller;

import cn.hutool.json.JSONUtil;
import cn.hutool.json.ObjectMapper;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpSession;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import spring.chatroom.java_chatroom.common.constant.Constants;
import spring.chatroom.java_chatroom.common.utils.*;
import spring.chatroom.java_chatroom.controller.pojo.AddFriendInfoReq;
import spring.chatroom.java_chatroom.mapper.ChatInfoMapper;
import spring.chatroom.java_chatroom.pojo.response.FriendListResp;
import spring.chatroom.java_chatroom.pojo.response.FriendSessionResp;
import spring.chatroom.java_chatroom.pojo.response.Response;
import spring.chatroom.java_chatroom.pojo.response.UserInfoResp;
import spring.chatroom.java_chatroom.server.MesSendServer;
import spring.chatroom.java_chatroom.pojo.model.ChatInfo;
import spring.chatroom.java_chatroom.pojo.model.SessionId;
import spring.chatroom.java_chatroom.pojo.model.UserInfo;
import spring.chatroom.java_chatroom.server.UserServer;

import java.io.IOException;
import java.util.*;

@RestController
@Slf4j
@RequestMapping("chat")
public class UserController {

    @Autowired
    UserServer userServer;

    @Autowired
    MesSendServer sendServer;

    @Autowired
    private RedisUtil redisUtil;

    /**
     * todo 根据id来获得用户的信息，并返回
     * 格式 userId userName
     */
    //获得用户的信息
    @RequestMapping("/userInfo")
    public Response UserInfo(@NotNull Integer userId) {
        log.info("UserInfo 获取用户信息 {}", userId);

        String s = redisUtil.getAndExpire(Constants.USERINFO + userId);
        if (s != null && !s.equals(Constants.REDIS_ERROR)) {
            //防止缓存穿透
            if(s.isEmpty()) return Response.success("不存在的user");
            return Response.success(SerializeUtil.unEncode(s, UserInfoResp.class));
        } else {
            UserInfoResp userInfo = userServer.getUserInfo(userId);
            redisUtil.set(Constants.USERINFO + userId, SerializeUtil.encode(userInfo));
            return Response.success(userInfo);
        }
    }

    /**
     * 获取到好友列表
     */
    @RequestMapping("/friendList")
    public Response friendList(@NotNull Integer userId) {
        log.info("friendList 获取好友列表 {}", userId);
        /**
         * todo 根据用户的id来获得他的朋友信息
         * 格式 SessionId friendId friendName
         */
        String s = redisUtil.get(Constants.FRIEND_LIST + userId);
        if (s != null && !s.equals(Constants.REDIS_ERROR)) {
            if(s.isEmpty()) return Response.success("不存在的user");

            List<FriendSessionResp> o = SerializeUtil.unEncodeList(s, FriendSessionResp.class);
            return Response.success(o);
        }

        List<FriendSessionResp> friendList = userServer.getFriendList(userId);
        redisUtil.set(Constants.FRIEND_LIST + userId, SerializeUtil.encode(friendList));

        return Response.success(friendList);
    }

    //这里转发加好友的信息 json
    @RequestMapping("tranFriendReq")
    public Response tranFriendReq(@RequestBody @NotNull AddFriendInfoReq data) throws IOException {
        log.info("转发发起的好友请求 {}", data.toString());

        return Response.success(userServer.tranFriendReq(data));
    }

    //加好友by id 返回SessionId 如果是赏了之后在加回去那么就只是吧之前的SessionId对应的delete_flag置为0

    /**
     * 表示接受方同意了请求，那么把这个消息发送给发送发，并把对应的好友请求从waitSend中删除
     * @param data：userId 接受方的id表示他同意了
     *            friendId 发送方的id
     */
    @RequestMapping("addFriends")
    public Response addFriends(@RequestBody @NotNull Map<String, Integer> data) throws IOException {
        log.info("addFriends 同意添加好友 {}", data.toString());

        Integer userId = data.get("userId");
        Integer friendId = data.get("friendId");

        SessionId SessionId = userServer.addFriends(userId, friendId);

        if (SessionId == null) {
            return Response.success(Map.of("status", "fail", "msg", "已经添加或者朋友不存在"));
        }

        //告诉对方
        sendServer.addFriendAgree(userId, friendId);

        return Response.success(Map.of("status", "success", "msg", SessionId));
    }

    /**
     * 表示接受方同意了请求，那么把这个消息发送给发送发，并把对应的好友请求从waitSend中删除
     * @param data：userId 接受方的id表示他同意了
     *            friendId 发送方的id
     */
    @RequestMapping("refuseFriends")
    public Response refuseFriends(@RequestBody @NotNull Map<String, Integer> data) throws IOException {
        log.info("refuseFriends 拒绝添加好友 {}", data.toString());

        Integer userId = data.get("userId");
        Integer friendId = data.get("friendId");

        //删除这个请求
        sendServer.deleteAddFriendReq(userId, friendId);

        return Response.success(Map.of("status", "success"));
    }

    //删除好友
    @RequestMapping("delFriend")
    public Response delFriend(@NotNull Integer sessionId) {
        log.info("delFriend 删除好友 {}", sessionId);

        userServer.delFriend(sessionId);

        return Response.success("");
    }

    //删除消息
    @RequestMapping("delMsg")
    public Response delMsg(@RequestBody Map<String, Integer> data) {
        log.info("delMsg 删除消息 {}", data.toString());

        Integer delId = data.get("delId");
        return Response.success(userServer.delMsg(delId));
    }

    /**
     * 获得朋友的聊天信息
     */
    @RequestMapping("/friendSessionList")
    public Response friendSessionList(@NotNull("friendSessionList 参数错误")  Integer userId) {
        log.info("friendSessionList 获得好友最近的聊天信息 {}", userId);
        /**
         * todo 根据用户的id来获得他的朋友信息 还要返回最近的消息
         * 格式 friendId friendName content
         */

        List<FriendListResp> friendSessionList = userServer.getFriendSessionList(userId);

        return Response.success(friendSessionList);
    }

    //获得的是聊天框的最近的聊天记录 左边的框
    @RequestMapping("getHistoryMessage")
    public Response getHistoryMessage(@NotNull("getHistoryMessage 参数错误") Integer sessionId) {
        log.info("getHistoryMessage 获取聊天记录 {}", sessionId);
        /**
         * todo 按降序排序 返回
         */
        return Response.success(userServer.sessionList(sessionId));
    }

    @RequestMapping("getOlineUser")
    public Response getOlineUser() {
        log.info("getOlineUser 获取到在线用户id");

        Set<Integer> ids = new HashSet<>(WebSocketSessionManagerUtil.getMap().keySet());

        ids.add(0);

        return Response.success(Map.of("status", "success", "msg", ids));
    }
}
